package com.sc.nft.controller;

import cn.hutool.extra.servlet.ServletUtil;
import com.sc.nft.annotation.UserLogin;
import com.sc.nft.controller.request.IdRequest;
import com.sc.nft.controller.request.TradingPoolOrderRequest;
import com.sc.nft.entity.dto.BusinessDTO;
import com.sc.nft.entity.dto.TradingPoolTransactionRecordsDTO;
import com.sc.nft.entity.vo.TradingPoolTransactionRecordsVO;
import com.sc.nft.entity.vo.tradingPool.TradingPoolOrderDetailVO;
import com.sc.nft.entity.vo.tradingPool.TradingPoolOrderVO;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.TradingPoolOrderService;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/tradingPoolOrder")
@Api(tags = "交易池订单")
public class TradingPoolOrderController {

    private final TradingPoolOrderService tradingPoolOrderService;

    private final Redisson redisson;


    @ApiOperation(value = "获取交易记录", notes = "获取交易记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/pageTransactionRecords", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<TradingPoolTransactionRecordsVO> pageTransactionRecords(@RequestBody @Valid TradingPoolTransactionRecordsDTO tradingPoolTransactionRecordsDTO) {
        return PageResult.success(tradingPoolOrderService.pageTransactionRecords(tradingPoolTransactionRecordsDTO));
    }

    @ApiOperation(value = "买入订单记录", notes = "买入订单记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/pageTradeInOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<TradingPoolOrderVO> pageTradeInOrder(@RequestBody @Valid TradingPoolOrderRequest pageRequest) {
        return PageResult.success(tradingPoolOrderService.pageTradeInOrder(pageRequest.getPageNo(), pageRequest.getPageSize(), pageRequest.getSearchTime(), UserPool.getUser().getId()));
    }

    @ApiOperation(value = "卖出订单记录", notes = "买入订单记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/pageTradeOutOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<TradingPoolOrderVO> pageTradeOutOrder(@RequestBody @Valid TradingPoolOrderRequest pageRequest) {
        return PageResult.success(tradingPoolOrderService.pageTradeOutOrder(pageRequest.getPageNo(), pageRequest.getPageSize(), pageRequest.getSearchTime(), UserPool.getUser().getId()));
    }

    @ApiOperation(value = "卖出买入订单详情", notes = "买入订单记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/tradeOrderDetail", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<TradingPoolOrderDetailVO> tradeOrderDetail(@RequestBody @Valid IdRequest idRequest) {
        return Result.success(tradingPoolOrderService.tradeOrderDetail(idRequest.getId()));
    }


    @ApiOperation(value = "买卖", notes = "买卖", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/business", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result business(@RequestBody @Valid BusinessDTO businessDTO, HttpServletRequest httpServletRequest) {
        // 加锁,锁的内容为daoId.
        RLock lock = redisson.getLock(RedisKeyEnum.TRADING_POOL_STOCK.getKey() + businessDTO.getDaoId());
        if (!lock.tryLock()) {
            throw new GlobalRunTimeException("当前购买人数过多，请稍后再试");
        }
        try {
            tradingPoolOrderService.business(businessDTO, UserPool.getUser(), ServletUtil.getClientIP(httpServletRequest));
        } catch (Exception e) {
            throw e;
        } finally {
            if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                lock.unlock();
            }
        }
        return Result.success();
    }
}
